<%
    Set as3Imports = new TreeSet();

    for (jImport in jClass.imports) {
        if (jImport.as3Type.hasPackage() && jImport.as3Type.packageName != jClass.as3Type.packageName)
            as3Imports.add(jImport.as3Type.qualifiedName);
    }

%>
package ${jClass.getAs3Type().getPackageName()}.base {
<%
///////////////////////////////////////////////////////////////////////////////
// Write Import Statements.
	%>
	import org.dbwebx.flex.delegate.AbstractRemotingDelegate;
	import mx.rpc.AsyncToken;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import org.swizframework.events.CentralDispatcher;
	import mx.rpc.remoting.mxml.RemoteObject;<%
    for (as3Import in as3Imports) {%>
    import ${as3Import};<%
    }
    for (as3Import in jClass.methodImports) {%>
    import ${as3Import};<%
    }

///////////////////////////////////////////////////////////////////////////////
// Write Class Declaration.%>

    [Bindable]
    public class ${jClass.as3Type.name}Base extends AbstractRemotingDelegate
    {
<%
	
	//Write public autowired fields
	%>
			[Autowire(bean="${jClass.as3Type.name}Remote")]
			public var remoteService:RemoteObject;
			
			public function ${jClass.as3Type.name}Base()
			{
				super();
			}
	<%
    ///////////////////////////////////////////////////////////////////////////
    // Write Private Fields.
    if(jClass.hasMethods()){
    	for (jMethod in jClass.methods) {%>
	        private function ${jMethod.name}Remote(<%
	        //set arguments
	        argsIterator=jMethod.arguments.size();
        	for (argument in jMethod.arguments) {%>${argument.getArgument()}:${argument.getType()}<%
        			argsIterator--;
        		    if(argsIterator>0){
        		    %>,<%
        		    }
	        }%>):AsyncToken 
	        {
	        	return executeCall(remoteService, "${jMethod.name}"<%
	        		if(jMethod.arguments.size()>0){
	        			%>, [<%
	        			argsIterator=jMethod.arguments.size();
			        	for (argument in jMethod.arguments) {%>${argument.getArgument()}<%
			        		argsIterator--;
		        		    if(argsIterator>0){
		        		    %>,<%
		        		    }
		        		}
		        		%>]<%
	        		}
	        		%>);
	        }
	        
			public function ${jMethod.name}(<%
				//write arguments
				for (argument in jMethod.arguments) {%>${argument.getArgument()}:${argument.getType()}, <%}%>eventArgs:Array = null):void
			{
				operation${jMethod.name} = resolveOperation("${jMethod.name}"<%
					//write arguments
				    argsIterator=jMethod.arguments.size();
					for (argument in jMethod.arguments) {
						    %>, <%
						    %>${argument.getArgument()}<%
					}%>);
				//check whether we can load data from local cache
				if(!isRemoteCallRequired(operation${jMethod.name}))
				{
					executeLocalCall(operation${jMethod.name}, ${jMethod.name}SuccessHandler, eventArgs);
				}
				else
				{
					executeServiceCall(${jMethod.name}Remote(<%
					//write arguments
				    argsIterator=jMethod.arguments.size();
					for (argument in jMethod.arguments) {%>${argument.getArgument()}<%
							argsIterator--;
						    if(argsIterator>0){
						    %>,<%
						    }
					}%>), ${jMethod.name}SuccessHandler, ${jMethod.name}FaultHandler, eventArgs);
				}
			}
			
			protected var operation${jMethod.name}:String;
			
			/**
			* do nothing should be overridden in subclass.
			*/
			protected function ${jMethod.name}SuccessHandler(result:ResultEvent, ... args:Array):void
			{
				if(result)
				{
					doCache(operation${jMethod.name}, result.result);
				}
			}
		
			protected function ${jMethod.name}FaultHandler(result:FaultEvent):void
			{
				CentralDispatcher.getInstance().genericFault(result);
			}
	    <%}
    }
    
    for (jProperty in jClass.properties) {%>
        private var _${jProperty.name}:${jProperty.as3Type.name};<%
    }

    ///////////////////////////////////////////////////////////////////////////
    // Write Public Getter/Setter.

    for (jProperty in jClass.properties) {
        if (jProperty.readable || jProperty.writable) {%>
<%
            if (jProperty.writable) {%>
        public function set ${jProperty.name}(value:${jProperty.as3Type.name}):void {
            _${jProperty.name} = value;
        }<%
            }
            if (jProperty.readable) {%>
        public function get ${jProperty.name}():${jProperty.as3Type.name} {
            return _${jProperty.name};
        }<%
            }
        }
    }%>    
    }
}